import CRC32 from 'CRC32';
import CRC16 from 'CRC16';
import AESUtil from 'aes-util';
import protobuf from '../weichatPb/protobuf';
import bluelock from '../proto/bluelock';
import {hex_md5} from 'MD5Util';
let _hex = require('lagden-hex'); // 载入第三方 npm 模块
var Buffer = require('buffer').Buffer, a = getApp();

let _seq = 1;  
let _isOldBlueVersion = false;
let _Data95 = null;
let bluelockRoot = protobuf.Root.fromJSON(bluelock);
let BaseResponse = bluelockRoot.lookupType("MmBp.BaseResponse");
let AuthRequest = bluelockRoot.lookupType("MmBp.AuthRequest");
let AuthResponse = bluelockRoot.lookupType("MmBp.AuthResponse");
let BaseRequest = bluelockRoot.lookupType("MmBp.BaseRequest");
let InitRequest = bluelockRoot.lookupType("MmBp.InitRequest");
let InitResponse = bluelockRoot.lookupType("MmBp.InitResponse");
let SendDataResponse = bluelockRoot.lookupType("MmBp.SendDataResponse");
let SendDataRequest = bluelockRoot.lookupType("MmBp.SendDataRequest");
let RecvDataPush = bluelockRoot.lookupType("MmBp.SendDataRequest");

// var payload = {Language: "我是test"};
// var message = AuthRequest.create(payload);
// var buffer = AuthRequest.encode(message).finish();
// console.log("buffer", buffer.toString('hex'));
// var deMessage = AuthRequest.decode(buffer);
// console.log("deMessage", deMessage);

Date.prototype.Format = function(fmt) { // author: meizz
    var o = {
        "M+": this.getMonth() + 1, // 月份
        "d+": this.getDate(), // 日
        "h+": this.getHours(), // 小时
        "m+": this.getMinutes(), // 分
        "s+": this.getSeconds(), // 秒
        "q+": Math.floor((this.getMonth() + 3) / 3), // 季度
        "S": this.getMilliseconds() // 毫秒
    };
    if (/(y+)/.test(fmt))
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

const EncryptUtil = {

    formatTime(second) {
        return [parseInt(second / 60 / 60), parseInt(second / 60 % 60), parseInt(second % 60)].join(":")
            .replace(/\b(\d)\b/g, "0$1");
    },

    getNowTimeStamp() {
        let tmp = Date.parse(new Date()).toString();
        tmp = tmp.substr(0, 10);
        return tmp;
    },

    isArrayFn(value) {
      console.log('typeOf-data', typeof (value), Array.isArray(value));
      if (typeof Array.isArray === "function") {
        return Array.isArray(value);
      } else {
        return Object.prototype.toString.call(value) === "[object Array]";
      }
    },

    //解析85数据
    parseData85(data, transferOpenLockCmd) {
        let _Data85 = null;
        if (data.length < 4) {
            console.info('【蓝牙连接】无效的85响应数据', data);
            return null;
        }
        console.log("85cmd--receiveData=",data);
        _Data85 = new Object();

        if (transferOpenLockCmd) {
          _Data85.command = '85';                    //指令
        } else {
          _Data85.command = parseInt(data[0]);     //指令
        }

        if (!this.isArrayFn(data)) {
           //2020新协议
          _Data85.isNew = 1;
          _Data85.backSeq = data.substring(10,12);
          if (_Data85.backSeq == 1) {
             //控制盒接收到命令
            _Data85.motorStat = data.substring(12,14);
            _Data85.mac = data.substring(22,34);
            _Data85.diffTime = data.substring(34, 42);
          } else if (_Data85.backSeq == 2) {
            //开锁完成
            _Data85.mac = data.substring(12, 24);
            _Data85.motorRunningTime = data.substring(24, 26);
            _Data85.rfid = data.substring(26,34);
            _Data85.lockStat = data.substring(34,36);
            _Data85.insertStat = data.substring(36,38);
            _Data85.lockErrCode = data.substring(38, 40);
            _Data85.noEject = data.substring(40,42);
            _Data85.retryEject = data.substring(42,44);
            _Data85.extraData = data.substring(44,data.length);
          }           
        } else {
          _Data85.isNew = 0;
          //旧协议
          //191101 之后的驱动
          if (_Data95 && _Data95.pile_ver && _Data95.pile_ver.slice(-6) >= '191101') { //两次85回执
            _Data85.isNew = 2;//新新驱动
            _Data85.backSeq = parseInt(data[1])
            if (_Data85.backSeq == 1) {//立即返回指令
              _Data85.motorStat = data[2];                 //马达运行状态 00正常  01正在运行
              _Data85.mac = data[3];                       //设备MAC地址
              _Data85.diffTime = data[4];                  //这个轮椅在此桩上待的时间（分钟）
            } else if (_Data85.backSeq == 2) {//开锁后返回指令
              _Data85.mac = data[2];                      //设备MAC地址
              _Data85.motorRunningTime = data[3];         //马达运行时间（秒）
              _Data85.rfid = data[4];                     //rfid
              _Data85.lockStat = data[5];                 //锁钩开关状态
              _Data85.insertStat = data[6];               //插入开关状态
              _Data85.lockErrCode = data[7];              //开锁错误码
              _Data85.noEject = data[8];                  //设备没弹出标记 0弹出  1未弹出
              _Data85.retryEject = data[9];               //重试弹出标记  0未重试 1重试了一次
            }
          } else {
            _Data85.rfid = data[1];                  //RFID
            _Data85.mac = data[2];                   //设备MAC地址
            _Data85.status = data[3];                //开锁状态
          }
        }

        console.log('_Data85-->',_Data85);
        return _Data85;

        
    },

    parseData98(data){//新固件/新协议 
       let _Data98 = new Array();
       _Data98.push(data.substring(8,10));
       _Data98.push(data.substring(10,14)); //2
       _Data98.push(data.substring(14, 22));//4
       _Data98.push(data.substring(22, 26));//2
       _Data98.push(data.substring(26, 34));//4
       _Data98.push(data.substring(34, 38));//2
       _Data98.push(data.substring(38, 46));//4
       _Data98.push(parseInt(data.substring(46, 54), 16) + '');//4  index7
       _Data98.push(parseInt(data.substring(54, 62), 16) + '');//4  index8
       _Data98.push(parseInt(data.substring(62, 66), 16) + '');//2  index9
       _Data98.push(data.substring(66, 68));//1
       _Data98.push(data.substring(68, 70));//1
       _Data98.push(data.substring(70, 78));//4
       _Data98.push(data.substring(78, 80));//1
       return _Data98;   
    },

    //解析95数据
    parseData95(data) {
        //收到95数据表示连接成功
        a.globalData.consuc = true;
        _Data95 = null;
        if (data.length < 5) {
            console.info('【蓝牙连接】无效的95响应数据', data);
            return _Data95;
        }
        console.log("95cmd--receiveData=", data);
        _Data95 = new Object();
        if (!this.isArrayFn(data)) {
          //2020新协议
          _Data95.command = data.substring(8, 10); //指令
          _Data95.rfid = data.substring(10, 18);              //RFID
          _Data95.mac = data.substring(18, 30);               //设备MAC地址
          _Data95.costTime = data.substring(30, 38);          //时间
          _Data95.electrict = parseInt(data.substring(38, 42), 16); //剩余电量
          _Data95.hookStatus = parseInt(data.substring(42, 44), 16);// 1不对 0对
          _Data95.powerOnCount = parseInt(data.substring(44, 48), 16);
          _Data95.chairSwitchSatus = parseInt(data.substring(48, 50), 16);
          _Data95.programRestartTimes = parseInt(data.substring(50, 52), 16);//滴滴两声 0非滴滴，1滴滴两声
          _Data95.programRestartErrCode = parseInt(data.substring(52, 56), 16);//自动修复次数
          _Data95.rfidIsCache = parseInt(data.substring(56, 58), 16);
          _Data95.rfidRepeatCount = parseInt(data.substring(58, 60), 16);
          _Data95.rfidReadErrCode = data.substring(60, 62);
          _Data95.motorStat = data.substring(62,64);
          _Data95.loseChair = data.substring(64, 66);
          _Data95.unlockErrCode = data.substring(66, 68);
          if(data.length > 72) {
            _Data95.chairIsEjectLose = parseInt(data.substring(68, 70), 16);
          }
          if(data.length > 74){
            //芯片的时钟计数器值
            _Data95.box_time = data.substring(70,78);
          }
          if(data.length > 82){
            //超出的参数
            _Data95.recent_electrict = parseInt(data.substring(78,82),16);
          }
          if(data.length > 86){
            //超出的参数
            _Data95.extVal = data.substring(82,data.length);
          }
          return _Data95;

        }


        _Data95.command = parseInt(data[0]); //指令
        _Data95.rfid = data[1];              //RFID
        _Data95.mac = data[2];               //设备MAC地址
        _Data95.costTime = data[3];          //时间
        _Data95.electrict = parseInt(data[4], 16); //剩余电量
        _Data95.hookStatus = -1;
        _Data95.powerOnCount = -1;
        _Data95.chairSwitchSatus = -1;
        _Data95.programRestartTimes = -1;
        _Data95.programRestartErrCode = -1;

        if (data.length >= 6) {
          _Data95.hookStatus = parseInt(data[5],16);
        }

        if (data.length >= 7) {
          _Data95.powerOnCount = parseInt(data[6]);
        }

        if (data.length >= 8) {
          _Data95.chairSwitchSatus = parseInt(data[7],16);
        }

        if (data.length >= 9) {
          //滴滴两声
          _Data95.programRestartTimes = parseInt(data[8],16);
        }

        if (data.length >= 10) {
          //自动修复次数
          _Data95.programRestartErrCode = parseInt(data[9],16);
        }

        if (data.length >= 11) {
          _Data95.rfidIsCache = parseInt(data[10],16);
        }
        if (data.length >= 12) {
          _Data95.rfidRepeatCount = parseInt(data[11],16);
        }
        if (data.length >= 13) {
          _Data95.rfidReadErrCode = data[12];
        }

        if(data.length >= 14) {
          _Data95.motorStat = data[13];
        }
        if(data.length >= 15) {
          _Data95.loseChair = data[14];
        }
        if(data.length >= 16) {
          _Data95.unlockErrCode = data[15];
        }
        if(data.length >= 17) {
          _Data95.chairIsEjectLose = parseInt(data[16], 16);
        }

        if(data.length >= 18) {
          _Data95.box_time = data[17];
        }
        if (data.length >= 19) {
          _Data95.pile_ver = data[18];
        }
        if (data.length >= 20) {
          _Data95.recent_electrict = data[19];
        }

        if (data.length >= 21) {
          var extVal = '';
          var len = data.length;
          for(var i=20;i<len;i++) {
            extVal += data[i];
            if(i < len - 1) {
              extVal += ",";
            }
          }
          _Data95.extVal = extVal;
        }

        return _Data95;
    },
    //解析格子柜第0包数据
    parse7500(data) {
      let data7500 = new Object();
      data7500.seqNum = data.substring(0,2);
      data7500.equStat = new Object();
      data7500.equStat.battery = data.substring(2,6);
      data7500.equStat.restartCount = data.substring(6,10);
      data7500.equStat.currentTime = data.substring(10,22);
      data7500.equStat.communicationType = data.substring(22,24);
      data7500.equStat.broadcastCycle = data.substring(24,26);
      data7500.equStat.maxDoorCount = data.substring(26,28);
      data7500.equStat.onlineDoorCount = data.substring(28,30);
      data7500.equStat.reserved = data.substring(30,32);
      data7500.reserved = data.substring(32,54);  
      return data7500;
    },
    //解析格子柜第N包数据
    parse75N(data) {
        let data75N = new Object();
        data75N.seqNum = data.substring(0,2);
        data75N.doorStat = new Object();
        let doorData = data.substring(2,22);
        data75N.doorStat.doorNum = doorData.substring(0,2);
        data75N.doorStat.doorStat = doorData.substring(2,4);
        data75N.doorStat.binStat = doorData.substring(4,6);
        data75N.doorStat.rfid = doorData.substring(6,14);
        data75N.doorStat.goodsStat = doorData.substring(14,16);
        data75N.doorStat.reserved = doorData.substring(16,20);
        data75N.reserved = data.substring(20,24);
        return data75N;
    },
    //解析格子柜的开锁结果
    parse76Data(data) {
        let data76 = new Object();
        data76.msgStat = data.substring(0,2);
        let doorStatData = data.substring(2,22);
        data76.doorInfo = new Object();
        data76.doorInfo.doorNum = doorStatData.substring(0,2);
        data76.doorInfo.doorStat = doorStatData.substring(2,4);
        data76.doorInfo.binStat = doorStatData.substring(4,6);
        data76.doorInfo.rfid = doorStatData.substring(6,14);
        data76.doorInfo.goodsStat = doorStatData.substring(14,16);
        data76.doorInfo.reserved = doorStatData.substring(16,20);

        data76.reserved = data.substring(22,24);

        return data76;
    },


  getBussinessData(ReceiveData, ReceivePacketLength, transferOpenLockCmd, isOld) {
    if (!ReceiveData){
      console.error('ReceiveData为空');
      return;
    }
    if (isOld) {
      return this.getOldBussinessData(ReceiveData, ReceivePacketLength, transferOpenLockCmd);
    }
    let that = this;

    let businessStr = ReceiveData.substring(0, ReceivePacketLength * 2);

    console.info('【蓝牙连接】接收业务数据完成...: isBusinessDataReceiveCompleted  received business data ');
    console.info('【蓝牙连接】完整业务数据： isBusinessDataReceiveCompleted  received business data ', businessStr);
    console.info('【蓝牙连接】业务数据HEX：', businessStr);

    let secret = businessStr.substring(4, businessStr.length - 4);
    console.log("业务数据--secret->", secret);
    secret = AESUtil.aesDecrypt(getApp().globalData._that, secret);
    console.log("95--data2->", secret);
    businessStr = businessStr.substring(0, 4) + secret + businessStr.substring(businessStr.length - 4);
    console.info('【蓝牙连接】业务数据解密HEX：', businessStr);

    let cmdId = businessStr.substring(8, 10);
    console.info('【蓝牙连接】cmdId：', cmdId);

    let data = null;
    if (cmdId == '88') {      
      data = that.parseData85(businessStr, transferOpenLockCmd);
    } else if (cmdId == '95') {
      data = that.parseData95(businessStr);
    } else if (cmdId == '75') {
      let seqNum = businessStr.substring(10,12);
      let params = businessStr.substring(10)
      if(seqNum == '00') {
        data = that.parse7500(params);
      }else {
        data = that.parse75N(params);
      }
    }else if(cmdId == '76'){
      
      let params = businessStr.substring(10)
      data = that.parse76Data(params);

    }  else if (cmdId == '98'){
      data = that.parseData98(businessStr);
    } else {
      data = businessStr;
      console.info('【蓝牙连接】未进行格式化的指令：', cmdId);
    }

    let businessData = {
      cmdId: cmdId,
      data: data
    };

    console.info('【蓝牙连接】解析后的业务数据：', businessData);

    return businessData;
  },

  getOldBussinessData(ReceiveData, ReceivePacketLength, transferOpenLockCmd) {
        let that = this;

        let businessStr = ReceiveData.substring(0, ReceivePacketLength * 2);

        console.log('【蓝牙连接】接收业务数据完成...: isBusinessDataReceiveCompleted  received business data ');
        console.log('【蓝牙连接】完整业务数据： isBusinessDataReceiveCompleted  received business data ', businessStr);
        let size = businessStr.substring(22, 24);
        console.log('【蓝牙连接】变长包数据长度： isBusinessDataReceiveCompleted  received business data: 1', size, parseInt(size, 16));
        businessStr = businessStr.substring(0, (12 + parseInt(size, 16)) * 2);
        console.log('【蓝牙连接】有效业务数据：isBusinessDataReceiveCompleted  received business data 2 ', businessStr);
        businessStr = businessStr.substring(48, (12 + parseInt(size, 16)) * 2);
        console.log('【蓝牙连接】最终业务数据： isBusinessDataReceiveCompleted  received business data 3', businessStr);

        let result = _hex.decode(businessStr, false);
        console.log('【蓝牙连接】业务数据HEX：', result, ReceiveData);

        let arr = result.split(',');
        console.log('【蓝牙连接】业务数据数组：', arr);
        let cmdId = arr[0];
        console.log('【蓝牙连接】cmdId：', cmdId);
       
        let data = null;
        if (cmdId == '85' || cmdId == '88') {
            if (cmdId == '88' && transferOpenLockCmd) {
                cmdId = '85';
            }
            data = that.parseData85(arr, transferOpenLockCmd);
        } else if (cmdId == '95') {
            data = that.parseData95(arr);
        }else if (cmdId == '75') {
          let seqNum = businessStr.substring(0,2);
          if(seqNum == '00') {
            data = that.parse7500(businessStr);
          }else {
            data = that.parse75N(businessStr);
          }
        }else if(cmdId == '76'){
            data = that.parse76Data(businessStr);
        } else {
            data = arr;
            console.log('【蓝牙连接】未进行格式化的指令：', cmdId);
        }

        let businessData = {
            cmdId: cmdId,
            data: data
        };

        console.log('【蓝牙连接】解析后的业务数据：', businessData);

        return businessData;
    },

    getSendDataRequestHexStr(sendData, isOld, version) {
      console.log("getSendDataRequestHexStr---------->", sendData, isOld, version)
      if (isOld) {
        return this.getOldSendDataRequestHexStr(sendData);
      }
      let that = this;
      let params = '00';
      if(sendData == '95') {
          params = '01';
      }
      
      if(sendData == '88' || sendData == '85') {
        var _that = getApp().globalData._that;
        params = _that && _that.data.conDevExtParams ? _that.data.conDevExtParams.broadcast88conf : "00";
      }    
      
      let sendHexStr = that.createSendMessage(sendData, params, isOld, version);
      return sendHexStr;
    },
    
    getOldSendDataRequestHexStr(sendData) {
      let that = this;

        var sendDataRequestObject = SendDataRequest.create({
            BaseRequest: BaseRequest.create({}),
            Data: that.hexStrToUint8Array(_hex.encode(sendData, false)),
            Type: 0
        });

        let sendHexStr = that.Uint8ArrayToHexStr(SendDataRequest.encode(sendDataRequestObject).finish());
        console.log('【蓝牙连接】准备发送指令数据：' + sendData);
        console.log('【蓝牙连接】变长包HEX数据：' + sendHexStr);
        sendHexStr = that.createOldSendMessage(30001, sendHexStr);
        console.log('【蓝牙连接】准备发送HEX数据：' + sendHexStr);
        return sendHexStr;
    },

    getInitResponseData(EncryptValue, TimeBytes, initRequestObject, UserIdHigh, UserIdLow, ErrCode, ErrMsg) {
        let that = this;

        //校验初始化数据正确性，这里目前未校验，默认认为是合法的设备
        let initResponseData = "FE0100194E2300020A02080010B42418F8AC0120D1BBCABF07";

        if (_isOldBlueVersion == false) {
            console.log('【蓝牙连接】当前采用新版本蓝牙连接协议！')
            var initResponseObject = InitResponse.create({
                BaseResponse: BaseResponse.create(
                    {
                        ErrCode: ErrCode,
                        ErrMsg: ErrMsg
                    }),
                UserIdHigh: UserIdHigh,
                UserIdLow: UserIdLow,
                ChalleangeAnswer: that.getAnswer(EncryptValue, that.getInitRequestPassword(initRequestObject)),
                TimeString: that.hexStrToUint8Array(TimeBytes)
            });

            console.log('【蓝牙连接】initResponseObject', initResponseObject);

            var initResponseBuffer = InitResponse.encode(initResponseObject).finish();

          initResponseData = that.createOldSendMessage(20003, that.Uint8ArrayToHexStr(initResponseBuffer));
        } else {
          console.log('【蓝牙连接】当前采用老版本蓝牙连接协议！')
        }

        console.log('【蓝牙连接】准备发送Init响应数据：' + initResponseData);

        return initResponseData;
    },

    getInitRequestPassword(initRequestObject) {
        let that = this;
        let password = that.Uint8ArrayToHexStr(initRequestObject.Challenge);
        console.log("【蓝牙连接】password：", password);
        return password;
    },

    parseInitRequest(ReceiveData, ReceivePacketLength, encryptValue, timeBytes) {
        let that = this;

        let dataStr = ReceiveData.substring(0, ReceivePacketLength * 2)

        let result = that.hexStrToString(dataStr, false);
        console.log("【蓝牙连接】解析Init数据：", result);
        console.log('【蓝牙连接】接收Init数据完成...');
        console.log('【蓝牙连接】完整Init数据：' + dataStr);
        console.log('【蓝牙连接】校验Init数据...');

        dataStr = dataStr.substring(16, ReceivePacketLength * 2);
        console.log("【蓝牙连接】INIT变长包数据：", dataStr);

        let initRequestObject = InitRequest.decode(that.hexStrToUint8Array(dataStr));
        console.log("【蓝牙连接】解析后的InitRequest对象：", initRequestObject);

        let password = that.getInitRequestPassword(initRequestObject);

        if (password == '11223344' || (encryptValue == null && timeBytes == null)) {
            _isOldBlueVersion = true;
        } else {
            _isOldBlueVersion = false;
        }

        return initRequestObject;
    },

    parseAuthRequest(ReceiveData, ReceivePacketLength) {
        let that = this;

        let dataStr = ReceiveData.substring(0, ReceivePacketLength * 2);

        let result = that.hexStrToString(dataStr, false);
        console.log("【蓝牙连接】解析AUTH数据：", result);
        console.log('【蓝牙连接】接收Auth数据完成...');
        console.log('【蓝牙连接】完整Auth数据：', dataStr);

        dataStr = dataStr.substring(16, ReceivePacketLength * 2);
        console.log("【蓝牙连接】AUTH变长包数据：", dataStr);

        var authRequest = AuthRequest.decode(that.hexStrToUint8Array(dataStr));
        console.log("【蓝牙连接】解析后的AuthRequest对象：", authRequest);
        return authRequest;
    },

    getAuthResponseData(sessionKey, ErrCode, ErrMsg) {
        let that = this;

        // let authResponseData = "FE01000E4E2100010A0208001200";
        let authResponseObject = AuthResponse.create(
            {
                BaseResponse: BaseResponse.create(
                    {
                        ErrCode: ErrCode,
                        ErrMsg: ErrMsg
                    }),
                AesSessionKey: sessionKey
            });
        let authResponseBuffer = AuthResponse.encode(authResponseObject).finish();

        console.log('【蓝牙连接】authResponseObject', authResponseObject);

        let authResponseData = that.createOldSendMessage(20001, that.Uint8ArrayToHexStr(authResponseBuffer));

        console.log('【蓝牙连接】准备发送Auth响应数据：' + authResponseData);

        return authResponseData;
    },


    createSendMessage(CmdId, message, isOld, version) {
      if (isOld) {
        return this.createOldSendMessage(CmdId, message);
      }

      let that = this;

      console.info("变长数据包内容------》：" + message);

      ++_seq;

      var seq = _seq.toString(16).toUpperCase();
      seq = that.padLast(seq, 2);
      var len = '12';//数据定长为18个字节
      len = that.padLast(len, 2);
      CmdId = that.padLast(CmdId, 2);


      var bMagicNumber = 'F5';
      var bVer = version&&version!='undefined'?version:'01';
      var nLength = len;
      var nCmdId = CmdId;
      var nSeq = seq;
      // console.log("----msgCmd=",CmdId);
      // console.log("----msgLen=",len);
      // console.log("----nSeq=",nSeq);

      var result1 = bMagicNumber + nLength + bVer + nSeq + nCmdId;
      message = that.padLast(message, (36 - result1.length));//额外参数补齐，总长20字节（包含校验码2个字节）
      let content = bVer + nSeq + nCmdId + message;
      console.log("cmd:" + nCmdId+";content:"+content);
      //加密      
      let msgPwd = AESUtil.aesEncrypt(getApp().globalData._that,content);
      console.log("cmd密文:" + nCmdId + ";content:" + msgPwd);


      var result2 = bMagicNumber + nLength + msgPwd;

      // console.log("数据--result1=",result1);
      console.log("数据--result2=",result2);
      // console.info("定长数据包长度：" + result1.length / 2);
      // console.info("变长数据包长度：" + message.length / 2);
      // console.info("完整数据包长度：" + result2.length / 2, len);

      let validateCode = CRC16.ToModbusCRC16(result2);
      // console.log("数据--validateCode=",result1);
      return result2 + validateCode;
    },

    createOldSendMessage(CmdId, message) {
        let that = this;

        console.log("变长数据包内容：" + message);

        CmdId = CmdId.toString(16).toUpperCase();
        CmdId = that.pad(CmdId, 4);

        ++_seq;

        var seq = _seq.toString(16).toUpperCase();
        seq = that.pad(seq, 4);

        var len = (8 + message.length / 2).toString(16).toUpperCase();
        len = that.pad(len, 4);

        var bMagicNumber = 'FE';
        var bVer = '01';
        var nLength = len;
        var nCmdId = CmdId;
        var nSeq = seq;

        var result1 = bMagicNumber + bVer + nLength + nCmdId + nSeq;
        var result2 = bMagicNumber + bVer + nLength + nCmdId + nSeq + message;

        console.log("定长数据包长度：" + result1.length / 2);
        console.log("变长数据包长度：" + message.length / 2);
        console.log("完整数据包长度：" + result2.length / 2, len);

        return result2;
    },

    hexStrToString(hexStr, flag) {
        if (flag) {
            flag = true;
        } else {
            flag = false;
        }
        return _hex.decode(hexStr, flag);
    },

    stringToHexStr(string, flag) {
        if (flag) {
            flag = true;
        } else {
            flag = false;
        }
        return _hex.encode(string, flag);
    },

    //Uint8Array转16进制字符串（结果是大写的）
    Uint8ArrayToHexStr(uint8Array) {
        return Array.prototype.map.call(uint8Array, x => ('00' + x.toString(16)).slice(-2)).join('').toUpperCase();
    },

    //16进制字符串转Uint8Array
    hexStrToUint8Array(hexStr) {
        var uint8Array = new Uint8Array(hexStr.match(/[\da-f]{2}/gi).map(function(h) {
            return parseInt(h, 16);
        }));
        return uint8Array;
    },

    pad(num, n) {
        var len = num.toString().length;
        while (len < n) {
            num = '0' + num;
            len++;
        }
        return num;
    },

    padLast(num, n) {
      var len = num.toString().length;
      while (len < n) {
        num = num + '0';
        len++;
      }
      return num;
    },

    getNowTime() {
        var result = new Date().Format("yyyy-MM-dd hh:mm:ss");
        console.log('getNowTime : ' + result);
        return result;
    },

    getTimeBytes(time) {
        console.log('getTimeBytes : ' + time);

        let that = this;

        //2018-10-06 22:55:11
        // ECI_resp_init，中，TimeString转义为KEY，格式为：
        // YMDHmS    4个字节32位：
        // Y： 7bits年的后两位   BYTE，0-127   可表示2000到2127年
        // M：4bits，0-11，表示1到12月。
        // D：5bits, 0-30，  表示1到31日。
        // H：5bits, 0-23
        // m：6bits, 0-60
        // S:  5bits, 0-30     秒数除以2.
        var year = parseInt(time.substring(0, 4)) - 2000;
        var month = parseInt(time.substring(5, 7));
        var date = parseInt(time.substring(8, 10));
        var hours = parseInt(time.substring(11, 13));
        var minutes = parseInt(time.substring(14, 16));
        var seconds = parseInt(parseInt(time.substring(17, 19)) / 2);

        console.log('getTimeBytes : ' + year.toString() + '-' + month.toString() + '-' + date.toString() + ' ' + hours.toString() + ':' + minutes.toString() + ':' + seconds.toString());

        year = that.pad(year.toString(2), 7);
        month = that.pad(month.toString(2), 4);
        date = that.pad(date.toString(2), 5);
        hours = that.pad(hours.toString(2), 5);
        minutes = that.pad(minutes.toString(2), 6);
        seconds = that.pad(seconds.toString(2), 5);

        var bin = year.toString() + month.toString() + date.toString() + hours.toString() + minutes.toString() + seconds.toString();
        console.log('getTimeBytes : ' + bin);
        var result = parseInt(bin, 2).toString(16).toUpperCase();
        console.log('getTimeBytes : ' + result);
        return result;
    },

    getMacBytes(mac) {
        let that = this;
        //蓝牙MAC地址(6bytes)+蓝牙MAC地址(中间4bytes)
        var result = mac.toString().toUpperCase() + mac.toString().substring(2, 10).toUpperCase();
        console.log('getMacBytes : ' + result);
        return result;
    },

    getServerEncryptValue(mac, timeBytes) {
        //VALUE1=MD5(蓝牙MAC地址(6bytes)+蓝牙MAC地址(中间4bytes)＋TimeString (4 bytes),此处是字符串拼接方式）=16BYTE
        let that = this;
        var result = that.getMacBytes(mac) + timeBytes;
        console.log('getServerEncryptValue hex: ' + result);
        var result = hex_md5(EncryptUtil.hexStrToString(result)).toUpperCase();
        console.log('getServerEncryptValue md5: ' + result);
        return result;
    },

    getAnswer(serverEncryptValue, password) {
        // Answer的算法为： 
        // Answer(4bytes)＝CRC32(VALUE1+password(4字节),此处是字符串拼接方式). 
        let that = this;
        var crc = CRC32.unsigned(Buffer.from(that.hexStrToUint8Array(serverEncryptValue)), 0);
        console.log('getAnswer crc1: ' + crc);
        crc = CRC32.unsigned(Buffer.from(that.hexStrToUint8Array(password)), crc);
        console.log('getAnswer crc2: ' + crc);
        // crc = CRC32.unsigned(Buffer.from(that.hexStrToUint8Array(serverEncryptValue + password)));
        // console.log('getAnswer crc3: ' + crc);
        // crc = that.pad(crc, 8);
        console.log('getAnswer : ' + crc);
        return crc;
    }

};

// let sendHexStr = EncryptUtil.getSendDataRequestHexStr('95');
// console.log(sendHexStr);

// let sendDataRequestObject = SendDataRequest.decode(EncryptUtil.hexStrToUint8Array('0A00120239351800'));

// let sendDataRequestObject = SendDataRequest.decode(EncryptUtil.hexStrToUint8Array('0A00122DFECF0001002D00010004000038352C46464646464646462C4535374132374346353436352C464646464646464618914E'));
// console.log(sendDataRequestObject);
// let arr = _hex.decode(EncryptUtil.Uint8ArrayToHexStr(sendDataRequestObject.Data), false);
// console.log(arr);
// console.log(_hex.encode(arr, false));

// console.log(sendDataRequestObject);
// console.log('fecf0103201030039352c46464646464646462c4535374132374346353436352c46464646464646462c46454631'.length);
// console.log(_hex.decode('fecf010e0104003830', false));

// var initReq = InitRequest.decode(EncryptUtil.hexStrToUint8Array('0A001A046AA42062'));

// console.log(initReq);

// var pass1 = '6AA42062';
// var pass2 = '00A40162';
// var arr1 = EncryptUtil.hexStrToUint8Array(pass1);
// var arr2 = EncryptUtil.hexStrToUint8Array(pass2);
// console.log(arr1);
// console.log(arr2);
// var arr3 = new Uint8Array(arr1.length + arr2.length);
// console.log(arr3);
// arr3.set(arr1, 0);
// arr3.set(arr2, arr1.length);
// console.log(arr3);

// var pass3 = pass1 + pass2;
// console.log(pass3);
// console.log(EncryptUtil.hexStrToUint8Array(pass3));

// console.log(EncryptUtil.hexStrToUint8Array('01'));

// console.log("md5:" + md5(EncryptUtil.getMacBytes('E06690C65E09')))

// var text = '\xE0\x66\x90\xC6\x5E\x09\x66\x90\xC6\x5E\x25\x4B\x99\xA2';
// var text = EncryptUtil.hexStrToString('E06690C65E096690C65E254B99A2');
// console.log(hex_md5(text));

export default EncryptUtil;
